﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Linq;
using System.Xml.Linq;
using ABC.Core.Extentions;
using ABC.Domain.Entities;
using System.Globalization;
using RosService.Data;

namespace ABC.Business.Models
{
    public class ClientsModel
    {
        private readonly RosModel rosModel;
        private readonly VkModel vkModel;
        public ClientsModel(RosModel rosModel, VkModel vkModel)
        {
            this.rosModel = rosModel;
            this.vkModel = vkModel;
        }
        public decimal RegisterClient(string userId, Dictionary<string, object> values)
        {
            var result = rosModel.AddEntity("Клиенты", "ФизическоеЛицо", values);
            rosModel.UpdateEntityValue(userId, "СписокКлиентов", rosModel.GetEntityValue<string>(userId, "СписокКлиентов") + result + ",");
            return result;
        }

        public void UpdateClient(string clientId, Dictionary<string, object> values)
        {
            foreach (var val in values)
            {
                rosModel.UpdateEntityValue(clientId, val.Key, val.Value);
            }
        }

        public void DeleteAvatar(string photoId, string userId)
        {
            rosModel.DeleteEntity(photoId, false);
            rosModel.UpdateEntityValue(userId, "СсылкаНаАватар", "");
        }

        public string SetAvatar(string userId, HttpPostedFileBase data)
        {
            var photoId = rosModel.SaveFile(userId, data);
            rosModel.UpdateEntityValue(userId, "СсылкаНаАватар", Convert.ToDecimal(photoId));
            return photoId.ToString();
        }

        public decimal GetClientAvatar(string userId)
        {
            return rosModel.GetEntityValue<decimal>(userId, "СсылкаНаАватар");
        }

        public string[] GetClientsId(string userId)
        {
            return rosModel.GetEntityValue<string>(userId, "СписокКлиентов").Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
        }

        public List<Contact> GetContactsClient(string clientId, string field, bool isNullIndex)
        {
            var count = 0;
            var result = new List<Contact>();
            while (true)
            {
                var valueField = rosModel.GetEntityValue<string>(clientId, field + (count == 0 && !isNullIndex ? "" : count.ToString()));
                if (!string.IsNullOrEmpty(valueField))
                {
                    var typeField = rosModel.GetEntityValue<string>(clientId, "Тип" + field + (count == 0 && !isNullIndex ? "" : count.ToString()));
                    result.Add(new Contact { Type = typeField, Value = valueField });
                    count++;
                }
                else
                {
                    break;
                }

            }
            return result;
        }

        public List<InfoClient> GetClients(string[] clientsId, string userId, string filter = "", bool loadSimpleClient = false)
        {
            var result = new List<InfoClient>();
            for (var i = 0; i < clientsId.Length; i++)
            {
                DataRow cl;
                if (string.IsNullOrEmpty(filter))
                {
                    cl = rosModel.GetEntityById("ФизическоеЛицо", clientsId[i],
                                new[]
                                                    {
                                                        "Имя", "Фамилия","Отчество"
                                                    });
                }
                else
                {

                    cl = rosModel.GetEntityById("ФизическоеЛицо", clientsId[i],
                                                new Dictionary<string, object> { { "НазваниеОбъекта", filter } },
                                                new[]
                                                    {
                                                        "Имя", "Фамилия","Отчество"
                                                    });
                }

                if (cl != null)
                {
                    var client = new InfoClient();
                    client.FirstName = cl["Имя"].ToString();
                    client.LastName = cl["Фамилия"].ToString();
                    client.MiddleName = cl["Отчество"].ToString();
                    client.Id = cl["id_node"].ToString();
                    if (loadSimpleClient)
                    {
                        client.Emails = GetContactsClient(clientsId[i], "Email", false);
                    }
                    client.Phones = GetContactsClient(clientsId[i], "ТелефонныйНомер", false);
                    client.ObjectsOfInsurance = GetObjectsOfInsuranceClient(clientsId[i], userId);
                    result.Add(client);
                }

            }
            return result;
        }
        public List<ObjectOfInsurance> GetObjects(string userId, string status, string filter = "")
        {
            var filters = new Dictionary<string, object>();
            if (status == "atwork")
            {
                filters.Add("Удален", false);
            }
            if (status == "delete")
            {
                filters.Add("Удален", true);
            }
            if (!string.IsNullOrEmpty(filter))
            {
                filters.Add("НазваниеОбъекта", filter);
            }
            var obg = rosModel.GetEntities(
                    "[Типы=ОбъектСтрахования;Колонки=(Марка, Модель, ГодВыпуска, Страхователь,СсылкаНаСтрахователя);Сортировки=(НазваниеОбъекта,Asc);Места=(" +
                    userId + ",1)]", filters).AsEnumerable();
            return obg.Select(x => new ObjectOfInsurance
                                                                                   {
                                                                                       FullNameInsurant = x["Страхователь"].ToString(),
                                                                                       Release = x["ГодВыпуска"].ToString(),
                                                                                       Model = x["Модель"].ToString(),
                                                                                       Manufacture = x["Марка"].ToString(),
                                                                                       InsurantId = x["СсылкаНаСтрахователя"].ToString(),
                                                                                       Id = x["id_node"].ToString(),
                                                                                   }).ToList();
        }

        public List<ObjectOfInsurance> GetObjectsOfInsuranceClient(string clientId, string userId)
        {
            return rosModel.GetEntities("ОбъектСтрахования", userId,
                                               new Dictionary<string, Query.НаправлениеСортировки>() { { "НазваниеОбъекта", Query.НаправлениеСортировки.Asc } },
                                               new Dictionary<string, object> { { "Удален", false }, { "СсылкаНаСтрахователя", clientId } },
                                               new[] { "Марка", "Модель", "ГодВыпуска" }).AsEnumerable().Select(x => new ObjectOfInsurance
                                               {
                                                   Id = x["id_node"].ToString(),
                                                   Manufacture = x["Марка"].ToString(),
                                                   Model = x["Модель"].ToString(),
                                                   Release = x["ГодВыпуска"].ToString()
                                               }).ToList();
        }

        public string GetListObjectsInsurance(string id)
        {
            return rosModel.GetEntityValue<string>(id, "СписокОбъектовСтрахования");
        }


        public FullInfoClient GetClient(string id, string userId)
        {
            var result = new FullInfoClient();
            var client = rosModel.GetEntityById("ФизическоеЛицо", id, new[]
                                                    {
                                                        "Имя", "Фамилия", "Отчество", "ДатаРождения", "ДатаПолученияПрав", "Заметки", "СсылкаНаАватар", "Отдел", "Компания", "Должность",
                                                        "СтажВождения", "Возраст", "Пол"
                                                    });
            if (client != null)
            {
                result.Id = client["id_node"].ToString();
                result.FirstName = client["Имя"].ToString();
                result.LastName = client["Фамилия"].ToString();
                result.MiddleName = client["Отчество"].ToString();
                result.Avatar = client["СсылкаНаАватар"].ToString();
                result.Post = client["Должность"].ToString();
                result.Department = client["Отдел"].ToString();
                result.Company = client["Компания"].ToString();
                result.Age = Int32.Parse(client["Возраст"].ToString());
                result.Sex = client["Пол"].ToString();
                result.Experience = Int32.Parse(client["СтажВождения"].ToString());
                result.BirthDay = rosModel.GetEntityValue<DateTime>(id, "ДатаРождения");
                result.DateLawToCar = rosModel.GetEntityValue<DateTime>(id, "ДатаПолученияПрав");
                result.Notes = client["Заметки"].ToString();
                result.Emails = GetContactsClient(id, "Email", false);
                result.Phones = GetContactsClient(id, "ТелефонныйНомер", false);
                result.Addresses = GetContactsClient(id, "Адрес", true);
                result.SocNets = GetContactsClient(id, "СоцСеть", true);
                result.Ims = GetContactsClient(id, "Im", true);
            }
            result.ObjectsOfInsurance = GetObjectsOfInsuranceClient(id, userId);
            return result;
        }

        public void DeleteClients(string userId, string[] clientsId)
        {
            var listId = string.Empty;
            foreach (var id in clientsId)
            {
                rosModel.UpdateEntityValue(id, "Удален", true);
                rosModel.UpdateEntityValue(id, "ДатаУдаленияОбъекта", DateTime.Now);
                listId += string.Format("{0};", id);
            }
            rosModel.UpdateEntityValue(userId, "СписокУдаленныхКлиентов", string.Format("{0}{1}", rosModel.GetEntityValue<string>(userId, "СписокУдаленныхКлиентов"), listId));
        }

        public void DeleteObjects(string userId, string[] objectsId)
        {
            var listId = string.Empty;
            foreach (var id in objectsId)
            {
                rosModel.UpdateEntityValue(id, "Удален", true);
                rosModel.UpdateEntityValue(id, "ДатаУдаленияОбъекта", DateTime.Now);
                listId += string.Format("{0};", id);
            }
        }

        public string[] GetClientsIdAtWork(string userId)
        {
            var deletedClientsId = rosModel.GetEntityValue<string>(userId, "СписокУдаленныхКлиентов").Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
            var clientsAllId = rosModel.GetEntityValue<string>(userId, "СписокКлиентов");
            foreach (var deletedId in deletedClientsId)
            {
                if (clientsAllId.IndexOf(deletedId) >= 0)
                {
                    clientsAllId = clientsAllId.Replace(string.Format("{0},", deletedId), "");
                }
            }
            return clientsAllId.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string GetStatusClientVk(string clientIdVk)
        {
            /*var url = string.Format(@"http://api.vk.com/api.php?api_id=7&uid=5845806");
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";*/
            var oRequest = WebRequest.Create(VkModel.GetLastSeen(clientIdVk));
            oRequest.Credentials = CredentialCache.DefaultCredentials;
            // Получаем ответ
            try
            {
                var oResponce = oRequest.GetResponse();
                var reader = XmlReader.Create(oResponce.GetResponseStream());
                var xml = XDocument.Load(reader);
                if (xml.Descendants("last_seen").Any())
                {
                    // ReSharper disable PossibleNullReferenceException
                    var sex = xml.Descendants("sex").FirstOrDefault().Value;
                    // ReSharper restore PossibleNullReferenceException
                    var time = xml.Descendants("last_seen").Descendants("time").FirstOrDefault();
                    if (time != null)
                    {
                        var date = DateTimeExtention.UnixTimeStampToDateTime(Double.Parse(time.Value));
                        switch (sex)
                        {
                            case "1":
                                return string.Format("заходила {0} в {1}", date.ToString("dd MMMM", CultureInfo.CreateSpecificCulture("ru-RU")), date.ToString("HH:mm"));
                            case "2":
                                return string.Format("заходил {0} в {1}", date.ToString("dd MMMM", CultureInfo.CreateSpecificCulture("ru-RU")), date.ToString("HH:mm"));
                        }
                    }
                }
                return "не удалось найти страницу";
            }
            catch (Exception)
            {
                return "не удалось найти страницу";
            }
        }

        public string AddDelivery(Dictionary<string, object> values)
        {
            return rosModel.AddEntity("ЗаявкиНаВызов", "Заявка", values).ToString();
        }
        public string AddProductToDelivery(string id, Dictionary<string, object> values)
        {
            return rosModel.AddEntity(id, "ПродуктЗаявки", values).ToString();
        }

        public List<TrashItem> GetDeleteClients(string userId, string query)
        {
            var deletedClientsId = rosModel.GetEntityValue<string>(userId, "СписокУдаленныхКлиентов").Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
            var result = new List<TrashItem>();
            var filters = new Dictionary<string, object>();
            if (!string.IsNullOrEmpty(query))
            {
                filters.Add("НазваниеОбъекта", query);
            }
            foreach (var clientId in deletedClientsId)
            {
                var client = rosModel.GetEntityById("ФизическоеЛицо", clientId, filters,
                                                    new[]
                                                        {
                                                            "ДатаСозданияОбъекта", "ДатаУдаленияОбъекта", "Названиеобъекта"
                                                        });
                if (client != null)
                {
                    var item = new TrashItem();
                    item.Id = client["id_node"].ToString();
                    item.DateCreate = DateTime.Parse(client["ДатаСозданияОбъекта"].ToString());
                    DateTime date;
                    item.DateDelete = DateTime.TryParse(client["ДатаУдаленияОбъекта"].ToString(), out date) ? date.ToString("dd MMMM yyyy HH:mm") : string.Empty;
                    item.Type = client["type"].ToString();
                    item.Name = client["Названиеобъекта"].ToString();
                    result.Add(item);
                }
            }
            return result;
        }
        public List<TrashItem> GetDeleteObjects(string userId, string query)
        {
            var filters = new Dictionary<string, object> { { "Удален", true } };
            if (!string.IsNullOrEmpty(query))
            {
                filters.Add("НазваниеОбъекта", query);
            }
            DateTime date;
            return
                rosModel.GetEntities(
                    "[Типы=ОбъектСтрахования;Колонки=(НазваниеОбъекта,ДатаУдаленияОбъекта,ДатаСозданияОбъекта);Сортировки=(НазваниеОбъекта,Asc);Места=(" +
                    userId + ",1)]", filters).Select(x => new TrashItem
                                                                                         {
                                                                                             Id = x["id_node"].ToString(),
                                                                                             DateCreate = DateTime.Parse(x["ДатаСозданияОбъекта"].ToString()),
                                                                                             DateDelete = DateTime.TryParse(x["ДатаУдаленияОбъекта"].ToString(), out date) ? date.ToString("dd MMMM yyyy HH:mm") : string.Empty,
                                                                                             Type = x["type"].ToString(),
                                                                                             Name = x["Названиеобъекта"].ToString()
                                                                                         }).ToList();
        }
        public void ForeverDeleteObjectsAndClients(string userId)
        {
            var deletedClientsId = rosModel.GetEntityValue<string>(userId, "СписокУдаленныхКлиентов").Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var clientId in deletedClientsId)
            {
                rosModel.DeleteEntity(clientId);
            }
            rosModel.UpdateEntityValue(userId, "СписокУдаленныхКлиентов", "");
            var deletedObjects = rosModel.GetEntities(
                "[Типы=ОбъектСтрахования;Колонки=(НазваниеОбъекта);Сортировки=(НазваниеОбъекта,Asc);Места=(" +
                userId + ",1)]", new Dictionary<string, object> { { "Удален", true } });
            foreach (var @object in deletedObjects)
            {
                rosModel.DeleteEntity(@object["id_node"].ToString());
            }
        }
        public Dictionary<string, string> GetDocuments(string type)
        {
            return
                rosModel.GetEntities(
                    "[Типы=ЭлементПакетДокументов;Колонки=(НазваниеОбъекта);Сортировки=(НазваниеОбъекта,Asc)];Места=(ПакетДокументов,1);Условия=(ТипПродукта," + type + ",Соодержит)]", new Dictionary<string, object>()).ToDictionary(
                        company => company["id_node"].ToString(),
                        company => company["НазваниеОбъекта"].ToString());
        }
    }
}
